
#include <memory>

class B {
protected:
    B() = default;
};

class D :public B{};

std::shared_ptr<B> GenProduct(){
    class C :public B{};
    std::shared_ptr<B> ret = std::make_shared<C>();
    return ret;
}
// 另有 how_call_virtualfun_inconstructor.cpp 文件中的个写法。
// 保护了构造函数后，在本类中提供静态函数，以产生对象，少了些弯弯绕绕。


void Test2();

int main(){
    //B obj;//   error: calling a protected constructor of class 'B'

    auto sptr = GenProduct();

    D dObj; //没问题正常编译

    Test2();
    return 0;
}

// 强迫症不用new用make_shared-应对非公有构造函数的丑陋解决
#include <memory>
#include <iostream>

class TestShared {
protected:
    TestShared(){}
    void CallFun() {
        //std::shared_ptr<TestShared> pObj = std::make_shared<TestShared>();
       // error C2248: “TestShared::TestShared”: 无法访问 
    }
    virtual void funcVirtual(){}//dynamic_pointer_cast 需要虚函数。。。
    // 向下转换没虚函数，直接编译不过(RTTI（运行时类型识别）需要虚函数表)， error: 'TestShared' is not polymorphic
};
class DeTestShared :public TestShared {
public:
  //  DeTestShared():TestShared() {}
};


void Test2()
{
    std::shared_ptr<DeTestShared> pObj = std::make_shared<DeTestShared>();
    std::shared_ptr<TestShared> pObjW = std::dynamic_pointer_cast<TestShared>(pObj);
    if (pObjW) {
        std::cout << "Hello World!\n";
    }

    // dynamic_pointer_cast 向下转换需要虚函数
    std::shared_ptr<TestShared> basePtr2 = std::make_shared<DeTestShared>();
    auto derivedPtr2 = std::dynamic_pointer_cast<DeTestShared>(basePtr2); // 向下转换需要虚函数，否则编译不过
    std::cout << "基类→派生: " << (derivedPtr2 ? "成功" : "失败") << std::endl;
}
